package com.zzyy.study.controller;

import com.zzyy.study.dto.UserPointsReq;
import com.zzyy.study.dto.UserRanking;
import jakarta.annotation.Resource;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@RestController
public class UserRankingController
{
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 批量将用户积分数据写入到redis的zset中
     * @param userPointsReqList
     * @return
     */
    @PostMapping("/addUserPoint")
    public boolean addUserPoint(@RequestBody List<UserPointsReq> userPointsReqList)
    {
        String key = "user:ranking";

        for (UserPointsReq userPointsReq : userPointsReqList)
        {
            String userId = userPointsReq.getUserId();
            //先按积分降序(从大到小)，积分相同时按照最后更新时间升序(从小到大)
            // 公式:score = 积分 + (1 - 时间戳/10的13次方)
            double score = userPointsReq.getPoints() + (1 - userPointsReq.getUpdateTime() / 1e13);

            this.stringRedisTemplate.opsForZSet().add(key, userId, score);
        }

        return true;
    }

    /**
     * 获取用户积分排行榜(倒序)
     * @param topN 前多少名
     * @return
     */
    @GetMapping("/userRankings")
    public List<UserRanking> userRankings(@RequestParam("topN") int topN)
    {
        String key = "user:ranking";

        Set<ZSetOperations.TypedTuple<String>> typedTuples = this.stringRedisTemplate.opsForZSet().reverseRangeWithScores(key, 0, topN - 1);

        List<UserRanking> userRankingList = new ArrayList<>();

        for (ZSetOperations.TypedTuple<String> typedTuple : typedTuples)
        {
            UserRanking userRanking = new UserRanking();
            userRanking.setUserId(typedTuple.getValue());
            userRanking.setRedisScore(typedTuple.getScore());
            userRankingList.add(userRanking);
        }
        return userRankingList;
    }

}
